#include <vector>
#include <string>
#include <fstream>
#include <cmath>
#include <stdexcept>
#include <random>
#include <iostream>

#ifndef NEURON_HPP
#define NEURON_HPP

// 神经元基类（抽象类）
class Neuron {
protected:
	// 激活函数（纯虚函数，由子类实现）
	virtual double actFunc(double x) const = 0;
	// 激活函数导数（纯虚函数，用于反向传播）
	virtual double actFuncDeriv(double x) const = 0;
	
public:
	std::vector<double> weights;  // 输入权重
	double bias;                  // 偏置项
	double pre_act;               // 激活前的值（加权和+偏置）
	double post_act;              // 激活后的值（输出）
	
	// 构造函数：初始化权重数量
	Neuron(size_t inputSize) : bias(0.0) {
		weights.resize(inputSize, 0.0);
	}
	
	// 计算神经元输出（纯虚函数接口）
	virtual double count(const std::vector<double>& inputs) = 0;
	
	// Public接口：获取激活函数导数（使用当前pre_act计算）
	double getActDeriv() const {
		return actFuncDeriv(pre_act);
	}
	
	// 虚析构函数
	virtual ~Neuron() = default;
};

// ReLU神经元（继承自Neuron基类）
class ReLUNeuron : public Neuron {
protected:
	// 实现ReLU激活函数
	double actFunc(double x) const override {
		return std::max(0.0, x);
	}
	
	// 实现ReLU导数（x>0时为1，否则为0）
	double actFuncDeriv(double x) const override {
		return x > 0.0 ? 1.0 : 0.0;
	}
	
public:
	// 构造函数：调用基类构造，并初始化权重（正态分布）
	ReLUNeuron(size_t inputSize) : Neuron(inputSize) {
		std::random_device rd;
		std::mt19937 gen(rd());
		// 权重初始化
		std::normal_distribution<double> dist(0.0, std::sqrt(2.0 / inputSize));
		for (auto& w : weights) {
			w = dist(gen);
		}
		bias = dist(gen);  // 偏置也用相同分布初始化
	}
	
	// 计算输出：加权和+偏置 -> 激活函数
	double count(const std::vector<double>& inputs) override {
		if (inputs.size() != weights.size()) {
			throw std::invalid_argument("输入维度与权重不匹配");
		}
		// 计算加权和+偏置（激活前的值）
		pre_act = bias;
		for (size_t i = 0; i < inputs.size(); ++i) {
			pre_act += inputs[i] * weights[i];
		}
		// 应用激活函数（输出值）
		post_act = actFunc(pre_act);
		return post_act;
	}
};

#endif